﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;

namespace AppUpgrader.Download
{
    public class DownloadWorker : AbstractWorker
    {
        public int BufferSize { get; set; }// 网络速度快的话可以设置大一点，慢的话可以小一点
        public String DownloadURL { get; set; }
        public String DownloadTo { get; set; }
        public DownloadWorker(String url, String localPath)
        {
            this.DownloadURL = url;
            this.DownloadTo = localPath;
            this.BufferSize = 512;
        }

        public void AsynDownloadFile()
        {
            Thread th = new Thread(new ThreadStart(SynDownloadFile));
            th.Start();
        }

        protected void SynDownloadFile()
        {
            WebClient client = new WebClient();
            Stream stream = client.OpenRead(DownloadURL);
            StreamReader reader = new StreamReader(stream);
            FileStream outputStream = new FileStream(DownloadTo, FileMode.OpenOrCreate);
            try
            {
                byte[] bBuffer = new byte[BufferSize];
                int nRealCount = stream.Read(bBuffer, 0, BufferSize);
                int total = 0;
                // 下载，一面读一面下载是最好的方式。这样就不用声明多大的数组了
                while (nRealCount > 0)
                {
                    total += nRealCount;
                    this.RaiseStateChanged(new StateChangedEventArgs() { Percent = total, Message = "已下载" + total+"bytes" });
                    outputStream.Write(bBuffer, 0, nRealCount);
                    nRealCount = stream.Read(bBuffer, 0, bBuffer.Length);
                }
                this.RaiseStateChanged(new StateChangedEventArgs() { Percent = total, Message = "下载已完成，共下载" + total + "bytes" });
                this.RaiseComplete(new StateChangedEventArgs() { Percent = total, Message = DownloadTo });
                LogUtils.WriteLog(String.Format("下载已完成,共下载{0}bytes",total));
            }
            catch (WebException exp)
            {
                throw exp;
            }
            finally
            {
                stream.Close();
                reader.Close();
                outputStream.Close();
            }
        }
    }
}
